<template>
  <a-modal
    v-model="isModalVisible"
    :width="currentWidth"
    :height="modalHeight"
    :dialog-style="{ top: '64px' }"
    :destroy-on-close="true"
    :z-index="1000"
    :mask-closable="false"
    :keyboard="true"
    @cancel="handleCancel"
  >
    <template slot="title">
      <div class="left-btn">
        <span class="function-run-text">语义转换新增列-编辑不符合规则的值</span>
        <span class="divider"></span>
        <a-tooltip
          v-for="(tip, index) in functionList"
          :key="index"
          placement="top"
        >
          <template slot="title">
            <span>{{ tip.tooltip }}</span>
          </template>
          <div
            class="btn function-btn-spacing"
            @click="clickFunction(tip.click)"
          >
            <a-icon-font :type="tip.icon" />
          </div>
        </a-tooltip>
      </div>
    </template>
    <template slot="footer">
      <span class="table-info"
        >共有 {{ editTableDataLength }} 个不符合规则需要修改的值</span
      >
      <a-button key="back" @click="handleCancel">
        取消
      </a-button>
      <a-button key="submit" type="primary" @click="handleOk">
        确认
      </a-button>
    </template>
    <div class="modal-content">
      <div class="table-box">
        <ux-grid
          :data="editTableData"
          :height="currentHeight"
          :row-height="rowHeight"
          :edit-config="{ trigger: 'click', mode: 'cell' }"
          :highlight-current-row="false"
          :stripe="true"
          use-virtual
          @header-click="_headerClick"
        >
          <ux-table-column
            :title="'序号'"
            type="index"
            width="70"
          ></ux-table-column>
          <ux-table-column title="源数据列">
            <ux-table-column
              :title="columnData.name"
              :field="columnData.name"
              width="250"
            >
              <template #header="{ column }">
                <!-- 数据类型 -->
                <a-icon-font :type="columnTypeIcon[columnData.desc]" />
                <!-- 语义 -->
                <span class="semantic-text">
                  |
                  {{
                    columnData.semantic
                      ? semanticMapping[columnData.semantic]
                        ? semanticMapping[columnData.semantic]
                        : columnData.semantic
                      : '无'
                  }}
                </span>
                <!-- 列名 -->
                <span class="column-name">{{ column.title }}</span>
              </template>
            </ux-table-column>
          </ux-table-column>
          <ux-table-column title="新数据列">
            <ux-table-column
              :edit-render="{ autofocus: '.new-column-input' }"
              :field="newColumnName"
              :title="newColumnName"
              width="240"
            >
              <template #header>
                <!-- 数据类型 -->
                <a-icon-font :type="columnTypeIcon[newColumnNameDesc]" />
                <!-- 语义 -->
                <span class="semantic-text">
                  |
                  {{
                    changeSemanticInfo.toSemantic
                      ? semanticMapping[changeSemanticInfo.toSemantic]
                        ? semanticMapping[changeSemanticInfo.toSemantic]
                        : changeSemanticInfo.toSemantic
                      : '无'
                  }}
                </span>
                <!-- 列名 -->
                <span v-if="!isEditingColumnName" class="column-name">{{
                  newColumnName
                }}</span>
                <!-- 编辑列名 -->
                <input
                  v-else
                  ref="nameInput"
                  v-model="newColumnName"
                  v-focus
                  class="column-name"
                  @blur="editingColumnNameBlur"
                  @keyup.enter="editingColumnNameBlur"
                />
              </template>
              <!-- 修改值 -->
              <span slot-scope="scope">
                {{ scope.row[newColumnName] }}
              </span>
              <!-- 修改输入框  -->
              <template #edit="{ row }">
                <input v-model="row[newColumnName]" class="new-column-input" />
              </template>
            </ux-table-column>
          </ux-table-column>
        </ux-grid>
      </div>
      <div v-if="changeSemanticInfo.toSemantic">
        <a-table
          bordered
          :data-source="dataSource"
          :columns="columns"
          :pagination="false"
        >
          <template slot="name" slot-scope="text">
            <editable-cell :text="text" />
          </template>
        </a-table>
      </div>
    </div>
  </a-modal>
</template>

<script lang="ts">
/**
 * 转换意义时修改不符合 规则的值
 */
import { Prop, Component, Vue, Watch, Emit } from 'vue-property-decorator'
import { columnTypeIcon } from '@/components/studio/data/node-edit-panel/column-type-semantic-icon'
import { IColumn } from '@/store/modules/dataview'
import { IChangeSemanticInfo } from '@/components/studio/data/node-edit-panel/interface'
import { semanticMapping } from '@/components/studio/data/node-edit-panel/column-type-semantic'
// @ts-ignore
import { UxGrid, UxTableColumn } from 'umy-table'
import { apiValidateTransform } from '@/api/data-clean'
import semanticTransformationRules from '@/components/studio/data/node-edit-panel/semantic-translation'

interface KeyValue {
  [key: string]: any
}

@Component({
  components: {
    UxGrid,
    UxTableColumn,
  },
  directives: {
    focus: {
      inserted: (element: any) => {
        element.focus()
      },
    },
  },
})
export default class SemanticTransitionCreateColumnView extends Vue {
  @Prop() columnData!: any // 当前列（原始列信息）
  @Prop() tableName!: any // 当前表
  @Prop({ default: [] }) columnList!: IColumn[] // 全部的列字段
  @Prop() semanticTransformationConfigInfo!: IChangeSemanticInfo // 修改语义 有不符合规则的值 等信息

  public semanticMapping = semanticMapping // 语义 - 中文
  // 不符合规则的值与 新修改的值的映射
  public update: { [key: string]: any } = {} // 校验和确认创建的时候用

  // 修改语义创建新列的信息
  public get changeSemanticInfo(): IChangeSemanticInfo | null {
    return this.semanticTransformationConfigInfo
  }

  // 规则数据
  public get dataSource(): any {
    return this.changeSemanticInfo
      ? semanticTransformationRules[this.changeSemanticInfo.toSemantic]
      : []
  }

  // 规则表头
  public columns = [
    {
      title: '基本数据类型',
      dataIndex: 'dataType',
    },
    {
      title: '格式/规则',
      dataIndex: 'format',
    },
    {
      title: '示例',
      dataIndex: 'sample',
    },
  ]

  // 需要修改的个数
  public get editTableDataLength() {
    return this.semanticTransformationConfigInfo?.value
      ? this.semanticTransformationConfigInfo.value.length
      : 0
  }

  // 编辑的表，(会有一个新输入列)
  public editTableData: any = null

  private isEditingColumnName: boolean = false // 新列名的编辑状态
  private isModalVisible: boolean = true // 对话框显示
  // 功能 list
  public functionList: any[] = [
    { tooltip: 'delete', click: 'bulkDelete', icon: 'iconicon-beifen5' },
  ]

  private columnTypeIcon = columnTypeIcon // 数据类型 icon
  private newColumnName: string = '' // 新列名
  private newColumnNameDesc: string = 'varchar' // 新列数据类型

  mounted() {
    this.editTableData = this.semanticTransformationConfigInfo?.value.map(
      (value: any) => {
        return { [this.columnData.name]: value }
      }
    )
    this.newColumnNameDesc = this.columnData.desc
    this.newColumnName = this.CreateNewColumnName()
  }

  // 关于表外观
  private rowHeight = 14 // 行高
  public get currentWidth(): number {
    return document.body.clientWidth
  }

  public get currentHeight(): number {
    return document.body.clientHeight - 64 - 110
  }

  public get modalHeight(): number {
    return document.body.clientHeight - 64
  }

  private CreateNewColumnName() {
    const newColumnName: string = `${this.columnName}_${this.columnData.semantic}`
    //  防止重名；
    let index = 1
    let i = 0
    const { length } = this.tableColumns
    while (i < length) {
      if (this.tableColumns[i].name === `${this.columnName}_${index}`) {
        index += 1
      } else {
        i += 1
      }
    }
    return index > 0 ? `${newColumnName}_${index}` : newColumnName
  }

  public get tableColumns() {
    return this.columnList
  }

  public get columnName() {
    return this.columnData?.name
  }

  // 多个功能 统一点击入口
  public clickFunction(functionName: string) {
    if (functionName === 'bulkDelete') {
      this.bulkDelete()
    }
  }

  /**
   *  工具栏 删除
   */
  public bulkDelete() {
    this.editTableData.forEach((v: any, i: number) => {
      // 改变数据DOM不更新的解决方案
      Vue.set(this.editTableData[i], this.newColumnName, '')
    })
  }

  /**
   * 重命名新列名
   */
  @Watch('newColumnName')
  private onColumnNameChange(newName: string, oldName: string) {
    // 不存在已有的列名
    if (!this.judgeHaveColumn(this.newColumnName)) {
      this.editTableData.forEach((column: any) => {
        column[newName] = column[oldName]
        delete column[oldName]
      })
    }
  }

  // 编辑列名失焦
  editingColumnNameBlur() {
    // 不存在已有的列名， isEditingColumnName 恢复 false (确实的时候使用)
    this.isEditingColumnName = this.judgeHaveColumn(this.newColumnName)
  }

  public judgeHaveColumn(newColumnName: string): boolean {
    const haveColumnName: boolean = this.tableColumns.some(
      (column: any) => column.name === newColumnName
    )
    if (haveColumnName) {
      this.$message.error('列名已存在，请重新输入')
    }
    return haveColumnName
  }

  /**
   * 确定后 语义验证转换二次校验
   */
  public async handleOk() {
    this.update = {}
    this.editTableData.forEach((row: any) => {
      this.update[`${row[this.columnName]}`] = row[this.newColumnName]
        ? row[this.newColumnName]
        : 'null'
    })
    const parameters = {
      col: this.columnData.name,
      type: this.columnData.desc,
      semantic: this.columnData.semantic,
      toSemantic: this.changeSemanticInfo?.toSemantic,
      update: this.update,
      table: this.tableName,
    }
    const response = await apiValidateTransform({ data: parameters })
    if (response.data.code === 100) {
      const { result } = response.data
      if (
        result[this.columnData.name] === false ||
        result[this.columnData.name].length > 0
      ) {
        this.$message.warn('修改后的值不符合规则， 请阅读规则确认值！', 2)
      } else {
        this.afterSecondCheckHandleOk()
      }
    }
  }

  public afterSecondCheckHandleOk() {
    if (this.isEditingColumnName) {
      this.$message.error('列名已存在，请重新输入')
      return
    }
    const editInfo: any = {
      columnName: this.newColumnName,
      update: this.update,
      toSemantic: this.semanticTransformationConfigInfo?.toSemantic,
    }
    this.$emit('change-semantic', editInfo)
  }

  /**
   * 编辑新列名
   */
  public _headerClick(column: any) {
    if (column.title === this.newColumnName) {
      this.isEditingColumnName = true
    }
  }

  /**
   * 关闭弹框
   */
  @Emit('config-cancel')
  public handleCancel() {
    this.isModalVisible = false
    this.editTableData = null
  }
}
</script>

<style lang="less" scoped>
.left-btn,
.right-btn {
  align-items: center;
  display: flex;

  .btn {
    align-items: center;
    border-radius: 2px;
    cursor: pointer;
    display: flex;
    font-size: 16px;
    padding: 4px;
    position: relative;

    &:hover {
      background-color: #f1f1f1;
    }
  }

  .divider {
    border-right: 1px solid #5d637e;
    height: 16px;
    margin: 0 5px;
    width: 1px;
  }

  .function-btn-spacing {
    margin: 0 10px;
  }
}

.left-btn {
  .btn {
    margin-right: 2px;
  }

  .function-run-text {
    color: #5d637e;
    font-size: 14px;
    margin-right: 10px;
  }
}

.table-info {
  float: left;
  line-height: 32px;
}

// modal content
.modal-content {
  display: flex;
}

.table-box {
  overflow-y: scroll;
  // height: 800px;
  width: 600px;
}

/deep/ .ant-modal-body {
  padding: 0;
}

/deep/ .col--actived {
  border: 2px solid #cbceff;
}

.new-column-input {
  border: 0;

  &:focus {
    border: 0;
    outline: none;
  }
}

.auto-filled {
  color: #222432;
  opacity: 0.5;
}

/deep/ .elx-header--row .col--group {
  background-color: rgba(103, 113, 252, 0.1);
  color: #373b52;
  font-size: 14px;
  text-align: center;
}

/deep/ .elx-header--row .col--group.col--last {
  background-color: rgba(255, 249, 226);
}

/deep/ .elx-cell {
  color: #373b52;
}

/deep/ .new-column-input {
  background-color: rgba(0, 0, 0, 0);
}

/deep/ .elx-table.border--full .elx-table--header-wrapper {
  background: none;
}

/deep/ .elx-header--column .elx-cell--edit-icon {
  display: none;
}

.column-name {
  border: 0;
  color: #5d637e;
  font-size: 12px;
  letter-spacing: 1.12px;
  line-height: 16px;
  margin-left: 8px;
}

.semantic-text {
  color: #6973ff;
  display: inline-block;
  font-size: 11px;
  font-weight: 400;
  margin-left: 6px;
}

/deep/ .elx-header--column .elx-cell--title {
  line-height: 1;
}

/deep/ .elx-table .elx-cell {
  height: 16px;
  line-height: 16px;
}

/deep/ .elx-table .elx-header--column:not(.col--ellipsis) {
  padding: 8px 0;
}

/deep/ .elx-table .elx-body--column.col--ellipsis > .elx-cell {
  color: #373b52;
  font-size: 12px;
}

/deep/ .elx-table.elx-editable .elx-body--column {
  height: 32px;
  padding: 6px 0;
}
</style>
